package com.ycwl.freetv;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApkChecksum;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.animation.AnimationUtils;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.core.content.FileProvider;

import com.google.gson.Gson;
import com.ycwl.freetv.utils.FileUtils;
import com.ycwl.freetv.utils.Http;
import com.ycwl.library.AssetsListManager;
import com.ycwl.library.MyX509TrustManager;
import com.ycwl.library.ParseUIFromJson;
import com.ycwl.library.Utils;

import net.erdfelt.android.apk.AndroidApk;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

public class AutoUpdater {
    public static final String TAG = "AutoUpdater";
    // 下载安装包的网络路径
    private String apkUrl = "http://8.134.209.85:8080/storage/2/app/";
    protected String checkUrl = apkUrl + "output-metadata.json";

    // 保存APK的文件名
    private static final String saveFileName = "my.apk";
    private static File apkFile;
    private static File ocurrentVersionFile;
    private static int currentVersionCode;

    // 下载线程
    private Thread downLoadThread;
    private int progress;// 当前进度
    // 应用程序Context
    private Context mContext;
    // 是否是最新的应用,默认为false
    private boolean isNew = false;
    private boolean intercept = false;
    // 进度条与通知UI刷新的handler和msg常量
    private ProgressBar mProgress;
    private TextView txtStatus;

    private static final int DOWN_UPDATE = 1;
    private static final int DOWN_OVER = 2;
    private static final int SHOWDOWN = 3;
    private static final int SHOW_LOCAL_UPDATE = 4;

    private static AppVersion appVersion;

    class AppVersion {
        public int version;
        public String applicationId;
        public String variantName;
        public String elementType;

        class Element {
            public String type;
            public String variantName;
            public int versionCode;
            public String versionName;
            public String outputFile;
        }

        List<Element> elements;
    }

    public AutoUpdater(Context context) {
        mContext = context;
    }

    public void ShowUpdateDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);

        Log.d(TAG,"ShowUpdateDialog");
        builder.setCancelable(false);
        builder.setTitle("软件版本更新");
        builder.setMessage("有最新的软件包，请下载并安装!");
        builder.setPositiveButton("立即下载", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ShowDownloadDialog();
            }
        });
        builder.setNegativeButton("以后再说", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        builder.create().show();
    }

    public void ShowLocalUpdateDialog(String apkUrl) {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setCancelable(false);
        builder.setTitle("软件版本更新");
        builder.setMessage("U盘中发现可用更新包，是否安装更新!");
        builder.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                File file = new File(apkUrl);
                if (file.exists()) {
                    apkFile = new File(apkUrl);
                    installAPK();
                } else {
                    Toast toast = Toast.makeText(mContext.getApplicationContext(), "文件已经被删除，无法安装", Toast.LENGTH_LONG);
                    toast.show();
                }
            }
        });
        builder.setNegativeButton("以后再说", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        builder.create().show();
    }

    private void ShowDownloadDialog() {
        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
        Log.d(TAG,"ShowDownloadDialog");
        dialog.setCancelable(false);
        dialog.setTitle("软件版本更新");
        LayoutInflater inflater = LayoutInflater.from(mContext);
        txtStatus = new TextView(mContext);
        txtStatus.setGravity(Gravity.CENTER);
        txtStatus.setText("开始下载");
        dialog.setView(txtStatus);

        dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                intercept = true;
            }
        });
        dialog.show();
        DownloadApk();
    }

    /**
     * 检查是否更新的内容
     */
    public void CheckUpdate() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                mContext.startActivity(intent);
            }
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG,"CheckUpdate start");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                Log.d(TAG,"CheckUpdate running");
                String localVersion = "1";
                try {
                    localVersion = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                }
                PackageInfo packageInfo;
                try {
                    packageInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
                    currentVersionCode = packageInfo.versionCode;
                    // 使用versionCode进行后续操作
                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                    return;
                }

                String versionStr = Http.doGet(checkUrl,null,null);
                if (versionStr.isEmpty()) {
                    return;
                }
                Gson gson = new Gson();
                appVersion = gson.fromJson(versionStr, AppVersion.class);

                if (!appVersion.applicationId.equals(packageInfo.packageName) || currentVersionCode >= appVersion.elements.get(0).versionCode) {
                    return;
                }
                ParseUIFromJson parseUIFromJson = new ParseUIFromJson();
                apkUrl = apkUrl + appVersion.elements.get(0).outputFile;
                mHandler.sendEmptyMessage(SHOWDOWN);

            }
        }).start();
    }

    public void checkUpdateFromUsb(String usbDir) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                mContext.startActivity(intent);
            }
        }
        PackageInfo packageInfo;
        try {
            packageInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
            currentVersionCode = packageInfo.versionCode;
            // 使用versionCode进行后续操作
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return;
        }
        // 从给定的路径中查找有没有apk文件
        List<String> apkList = FileUtils.scanFileInByDir(usbDir,".*\\.(apk|APK)$",1);
        for (String path : apkList) {
            try {
                AndroidApk apk = new AndroidApk(new File(path));
                if (Integer.parseInt(apk.getAppVersionCode()) > currentVersionCode && packageInfo.packageName.equals(apk.getPackageName())) {
                    Message message = new Message();
                    message.what = SHOW_LOCAL_UPDATE;
                    message.obj = path;
                    mHandler.sendMessage(message);
                    break;
                }
            } catch (IOException ignored) {

            }
        }
    }

    /**
     * 从服务器下载APK安装包
     */
    public void DownloadApk() {
        downLoadThread = new Thread(DownApkWork);
        downLoadThread.start();
    }

    private Runnable DownApkWork = new Runnable() {
        @Override
        public void run() {
            URL url;
            try {

                //如果下载地址是HTTPS，则把这段加上，http则不需要
                SSLContext sslContext = SSLContext.getInstance("SSL");//第一个参数为 返回实现指定安全套接字协议的SSLContext对象。第二个为提供者
                TrustManager[] tm = {new MyX509TrustManager()};
                sslContext.init(null, tm, new SecureRandom());
                SSLSocketFactory ssf = sslContext.getSocketFactory();


                url = new URL(apkUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.connect();
                int length = conn.getContentLength();
                InputStream ins = conn.getInputStream();
                FileOutputStream fos = new FileOutputStream(apkFile);
                int count = 0;
                byte[] buf = new byte[1024];
                while (!intercept) {
                    int numread = ins.read(buf);
                    count += numread;
                    progress = (int) (((float) count / length) * 100);
                    Log.d(TAG,"DownloadApk:"+progress+"%");
                    // 下载进度
                    mHandler.sendEmptyMessage(DOWN_UPDATE);
                    if (numread <= 0) {
                        // 下载完成通知安装
                        mHandler.sendEmptyMessage(DOWN_OVER);
                        break;
                    }
                    fos.write(buf, 0, numread);
                }
                fos.close();
                ins.close();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 安装APK内容
     */
    public void installAPK() {
        try {
            if (!apkFile.exists()) {
                return;
            }

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//安装完成后打开新版本
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 给目标应用一个临时授权
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0
                //如果SDK版本>=24，即：Build.VERSION.SDK_INT >= 24，使用FileProvider兼容安装apk
                String packageName = mContext.getApplicationContext().getPackageName();
                String authority = new StringBuilder(packageName).append(".FileProvider").toString();
                Uri apkUri = FileProvider.getUriForFile(mContext, authority, apkFile);
                intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
            }
            mContext.startActivity(intent);
            android.os.Process.killProcess(android.os.Process.myPid());//安装完之后会提示”完成” “打开”。


        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    public void installApk_new(File apkFile) {
        PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        try {
            int sessionId = packageInstaller.createSession(params);
            // 确认安装提示，android11必备
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(apkFile),"application/vnd.android.package-archive");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
            intent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, mContext.getPackageName());
            mContext.startActivity(intent);


            PackageInstaller.Session session = packageInstaller.openSession(sessionId);
            if (apkFile.isFile() && apkFile.canRead()) {
                FileInputStream is = new FileInputStream(apkFile);
                OutputStream os = session.openWrite("base.apk",0,-1);
                byte[] buf = new byte[65536];
                int byteRead;
                while ((byteRead = is.read(buf)) != -1) {
                    os.write(buf, 0,byteRead);
                }

                os.close();
                is.close();
            } else {
                Log.e(TAG,"read apk file error");
            }

            session.commit(PendingIntent.getBroadcast(mContext,sessionId,new Intent(Intent.ACTION_MAIN), PendingIntent.FLAG_UPDATE_CURRENT).getIntentSender());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private Handler mHandler = new Handler(Looper.myLooper()) {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case SHOWDOWN:
                    ShowUpdateDialog();
                    break;
                case DOWN_UPDATE:
                    txtStatus.setText("当前下载进度:"+progress + "%");
                    break;
                case DOWN_OVER:
                    txtStatus.setText("当前下载进度:100%");
                    Toast.makeText(mContext, "下载完毕", Toast.LENGTH_SHORT).show();
                    installAPK();
                    break;
                case SHOW_LOCAL_UPDATE:
                    ShowLocalUpdateDialog((String)msg.obj);
                default:
                    Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };
}